package com.gupao.edu.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;

/**
 * @description：
 * @author：huabin.lin@xhmh.com
 * @version：2018年11月10日 10:48
 */
public class NettyServer {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("启动Server...");
        NettyServer server = new NettyServer();
        server.start();
    }

    /***
     * 服务端的默认IP地址
     */
    private static final String IP = "127.0.0.1";
    /***
     * 服务端的默认端口
     */
    private static final int PORT = 11111;
    /***
     * 设置BOSS线程池的大小(默认：CPU核心数 * 2)
     */
    private static final int BIZ_GROUP_SIZE = Runtime.getRuntime().availableProcessors();
    /***
     * 设置Work线程池的大小
     */
    private static final int BIZ_THREAD_SIZE = 100;

    /***
     * 创建负责Acceptor客户端的TCP连接的Reactor线程池
     */
    private static final EventLoopGroup bossGroup = new NioEventLoopGroup(BIZ_GROUP_SIZE);
    /***
     * 创建负责I/O读写操作的Reactor线程池
     */
    private static final EventLoopGroup workGroup = new NioEventLoopGroup(BIZ_THREAD_SIZE);

    /***
     * 启动服务端
     * @throws InterruptedException
     */
    public void start() throws InterruptedException {
        // 初始化ServerBootstrap实例，作为Netty服务端的入口
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(bossGroup, workGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<Channel>() {

                    @Override
                    protected void initChannel(Channel channel) throws Exception {
                        ChannelPipeline pipeline = channel.pipeline();
                        // 添加长度解码器，指定相应的参数
                        pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
                        // 添加String解码器
                        pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
                        // 田间String编码器
                        pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
                        // 添加业务逻辑处理器
                        pipeline.addLast(new TcpServerHandler());
                    }
                });

        // 阻塞绑定IP和监听端口
        ChannelFuture channelFuture = bootstrap.bind(IP, PORT).sync();
        // 监听服务端关闭
        channelFuture.channel().closeFuture().sync();

        System.out.println("Server start...");
    }

    /***
     * 关闭服务端
     */
    private void shutdown() {
        bossGroup.shutdownGracefully();
        workGroup.shutdownGracefully();
    }
}
